#include <windows.h>
#include "MySQL/mysql.h"

#include "CDb.h"
#include "CConsole.h"
#include "CModifier.h"
#include "CSemaphore.h"
#include "CArmorItem.h"

CArmorItem::CArmorItem(unsigned short itemID) {
	m_reqLvl = 1;
	m_modelID = 0;
	m_subModelID = 0;
	m_removeSlotID = 0;
	m_equipSlotID = SLOT_HEAD;

	m_defense = 0;

	modList.clear();

	modListSemaphore = new CSemaphore(1);
	
	setId(itemID);
	setType(ITEM_ARMOR);
	loadStats();
}

CArmorItem::~CArmorItem() {
	modList.clear();
	lockModifierList();
	delete modListSemaphore;
}

void CArmorItem::unlockModifierList(void)
{
	modListSemaphore->unlock();
	return;
}

void CArmorItem::lockModifierList(void) 
{
	modListSemaphore->lock();
	return;
}

void CArmorItem::loadStats() {
	MYSQL_RES * res;
	MYSQL_ROW row;
	char query[8192];
	unsigned long count;

	memset(query, 0, 8192);
	// Missing shield size for future use
	sprintf(query, "SELECT sa.Slot, sa.RemoveSlot, sa.mID, sa.submid, sa.DEF, iv.BaseSell FROM stats_armor AS sa LEFT JOIN item_values AS iv ON (sa.ItemID = iv.ItemID) WHERE sa.ItemID = %i", this->getId());
	count = (int) strlen(query);
	MYSQL * mysqlConn=CDb::getConn(); //get conn
	mysql_real_query(mysqlConn, query, count);
	res = mysql_store_result(mysqlConn);
	CDb::pushConn(mysqlConn); //release conn
	if(!res) {
		CConsole::outDebOnly("Error looking up armor stats.");
	} else if(mysql_num_rows(res)){
		row = mysql_fetch_row(res);
		unsigned char databaseSlotID = atoi(row[0]);
		unsigned short subModelID = 0;
		subModelID = atoi(row[3]);
		switch(databaseSlotID) {
			case DB_SLOTHEAD:
				setEquipSlotId(SLOT_HEAD);
				setModelId(atoi(row[2]) - 0x1000);
				break;
			case DB_SLOTBODY:
				setEquipSlotId(SLOT_BODY);
				setModelId(atoi(row[2]) - 0x2000);
				if(subModelID > 0)
					setSubModelId(atoi(row[3]) - 0x3000);
				break;
			case DB_SLOTHANDS:
				setEquipSlotId(SLOT_HANDS);
				setModelId(atoi(row[2]) - 0x3000);
				break;
			case DB_SLOTLEGS:
				setEquipSlotId(SLOT_LEGS);
				setModelId(atoi(row[2]) - 0x4000);
				if(subModelID > 0)
					setSubModelId(atoi(row[3]) - 0x5000);
				break;
			case DB_SLOTFEET:
				setEquipSlotId(SLOT_FEET);
				setModelId(atoi(row[2]) - 0x5000);
				break;
			case DB_SLOTOFFHAND:
				setEquipSlotId(SLOT_OFF);
				setModelId(atoi(row[2]) - 0x7000);
				break;
			case DB_SLOTNECK:
				setEquipSlotId(SLOT_NECK);
				break;
			case DB_SLOTWAIST:
				setEquipSlotId(SLOT_WAIST);
				break;
			case DB_SLOTEAR:
				setEquipSlotId(SLOT_EAR1);
				break;
			case DB_SLOTRING:
				setEquipSlotId(SLOT_RING1);
				break;
			case DB_SLOTBACK:
				setEquipSlotId(SLOT_BACK);
				break;
		}
		unsigned char removeSlotID = atoi(row[1]);
		switch(removeSlotID) {
			case DB_SLOTHEAD:
				setRemoveSlotId(SLOT_HEAD);
				break;
			case DB_SLOTHANDS:
				setRemoveSlotId(SLOT_HANDS);
				break;
			case DB_SLOTFEET:
				setRemoveSlotId(SLOT_FEET);
				break;
		}
		setDefense(atoi(row[4]));
		setSellPrice(atoi(row[5]));
		// rest are modifiers.  to be added
		loadModifiers();
	}
	mysql_free_result(res);
}

void CArmorItem::setModelId(unsigned short modelID) {
	m_modelID = modelID;
}

unsigned short CArmorItem::getModelId() {
	return m_modelID;
}

void CArmorItem::setSubModelId(unsigned short subModelID) {
	m_subModelID = subModelID;
}

unsigned short CArmorItem::getSubModelId() {
	return m_subModelID;
}

void CArmorItem::setEquipSlotId(unsigned char equipSlotID) {
	m_equipSlotID = equipSlotID;
}

unsigned char CArmorItem::getEquipSlotId() {
	return m_equipSlotID;
}

void CArmorItem::setRemoveSlotId(unsigned char removeSlotID) {
	m_removeSlotID = removeSlotID;
}

unsigned char CArmorItem::getRemoveSlotId() {
	return m_removeSlotID;
}

void CArmorItem::setReqLvl(unsigned char level) {
	m_reqLvl = level;
}

unsigned char CArmorItem::getReqLvl() {
	return m_reqLvl;
}

void CArmorItem::addMod(unsigned char modifier, char amount) {
	CModifier * newMod = new CModifier;
	newMod->setModID(modifier);
	newMod->setModAmount(amount);
	lockModifierList();
	modList.push_back(newMod);
	unlockModifierList();
}

char CArmorItem::getModAmount(unsigned char modifier) {
	lockModifierList();
	for(unsigned char count = 0; count < modList.size(); count++) {
		CModifier * mod = modList.at(count);
		if(mod->getModID() == modifier) {
			unlockModifierList();
			return mod->getModAmount();
		}
	}
	unlockModifierList();
	return 0;
}

void CArmorItem::setDefense(char defense) {
	m_defense = defense;
}

char CArmorItem::getDefense() {
	return m_defense;
}

void CArmorItem::loadModifiers() {
	
	MYSQL_RES * res;
	MYSQL_ROW row;
	char query[8192];
	unsigned long count;

	memset(query, 0, 8192);
	// Standard Modifiers
	sprintf(query, "SELECT `ItemID`, `DEF`, `HP`, `HP%%`, `ConvertMPtoHP`, `MP`, `MP%%`, `ConvertHPtoMP` ,`str`, `dex`, `vit`, `agi`, `int`, `mnd`, `chr`");
	sprintf(query, "%s, `Fire`, `Ice`, `Air`, `Earth`, `Thunder`, `Water`, `Light`, `Dark`, `Attack`, `Rattack`, `Accuracy`, `RAccuracy`, `Enmity`", query);
	sprintf(query, "%s FROM stats_armor WHERE ItemID = %i", query, this->getId());
	count = (int) strlen(query);
	MYSQL * mysqlConn=CDb::getConn(); //get conn
	mysql_real_query(mysqlConn, query, count);
	res = mysql_store_result(mysqlConn);
	CDb::pushConn(mysqlConn); //release conn
	if(!res) {
		CConsole::outDebOnly("Error looking up standard armor stats.");
	} else if(mysql_num_rows(res)){
		row = mysql_fetch_row(res);
		//Standard Modifiers start at 0x01(MOD_DEF) and are retrieved in order.
		for(unsigned char modType = 1; modType <= 27; modType++) {
			char modAmount = 0;
			modAmount = atoi(row[modType]);
			if( (modAmount > 0) || (modAmount < 0) )
				addMod(modType, modAmount);
		}
	}
	mysql_free_result(res);
}

void CArmorItem::loadAdditionModifiers() {
}

